package com.k2data.k2app.service.pas14;

import com.k2data.k2app.domain.pas14.project.*;
import com.k2data.k2app.domain.po.TaskDTO;
import com.k2data.k2app.domain.vo.Device;
import com.k2data.k2app.domain.vo.LabelValueKeyObject;
import com.k2data.k2app.domain.vo.Model;
import com.k2data.k2app.util.DateFormatterUtil;
import com.k2data.k2app.utils.StringUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 预警处理
 * @author clb
 * @Date  17-4-18.
 */
@Log4j2
@Service
public class Model14Service {

	@Autowired
	private Pas14ProjectService pas14ProjectService;
	/**
	 *  根据 [id] 查询模型
	 */
	public Model get(Long modelId)  throws Exception{
		Project project = pas14ProjectService.getBasic(modelId);
		if(project== null){
			return null;
		}
		Model model = projectToModel(project);
		return model;
	}

	/**
	 * pas项目转为model
	 */
	public List<Model> list() throws Exception {
		Map<String,String> map = new HashMap<>(16);
		map.put("owner",pas14ProjectService.getOwner());
		map.put("page","1");
		map.put("size","1000");
		List<Project> projects = pas14ProjectService.listBasic(map);
		List<Model> models = new ArrayList<>();
		for(Project project : projects){
			Model model = projectToModel(project);
			models.add(model);
		}
		return models;
	}

	public Long delete(Long modelId) throws Exception {
		pas14ProjectService.delete(modelId);
		return modelId;
	}

	public Long run(Long projectId) throws Exception {
		return Long.parseLong(pas14ProjectService.run(projectId));
	}

	public Long copyAndEdit(TaskDTO taskDTO) throws Exception {
		//1 复制模型
		String now = DateFormatterUtil.getNow(DateFormatterUtil.dateTimeFormatter1);
		String newProjName = taskDTO.getResult()+"_"+taskDTO.getModelId()+"_"+now;
		Project project = pas14ProjectService.copy(taskDTO.getModelId(),newProjName);
		//2 编辑模型
		String owner = project.getOwner();
		project.setOwner(owner+"_copy");
		pas14ProjectService.editBasic(project);
		// 2 编辑模型数据源节点信息
		ProjectNode[] nodes = project.getFlow().getNodes();
		for(ProjectNode node:nodes){
			if(node.getType().equals("data-set")){
				editDataSet(project.getId(),node.getId(),taskDTO);
			}else{
				editScriptAlg(project.getId(),node.getId(),taskDTO);
			}
		}

		return project.getId();
	}

	public Long edit(TaskDTO taskDTO) throws Exception {
		Project project = pas14ProjectService.getBasic(taskDTO.getModelIdCopy());
		// 2 编辑模型数据源节点信息
//		ProjectNode[] nodes = project.getFlow().getNodes();
		ProjectFlow flow = pas14ProjectService.getFlow(project.getId());
		ProjectNode[] nodes = flow.getNodes();
		for(ProjectNode node:nodes){
			if(node.getType().equals("data-set")){
				editDataSet(project.getId(),node.getId(),taskDTO);
			}else{
				editScriptAlg(project.getId(),node.getId(),taskDTO);
			}
		}
		return project.getId();
	}

	/**
	 * 修改计算节点信息
	 * @param projectId
	 * @param nodeId
	 * @param taskDTO
	 * @return
	 * @throws Exception
	 */
	public ProjectScriptAlg editScriptAlg(Long projectId,String nodeId,TaskDTO taskDTO) throws Exception {
		ProjectScriptAlg projectScriptAlg = pas14ProjectService.getScriptAlg(projectId,nodeId);
		List<InParam> list = new ArrayList<InParam>();
		// 算法输入参数【设备编号】
		// 算法输入参数【算法指标】
		if(!StringUtils.isEmpty(taskDTO.getAnalysisParamName()) && !StringUtils.isEmpty(taskDTO.getAnalysisParamValue())){
			InParam inParam1 = new InParam();
			inParam1.setType("DOUBLE");
			inParam1.setName(taskDTO.getAnalysisParamName());
			inParam1.setValue(taskDTO.getAnalysisParamValue());
			list.add(inParam1);
		}
		projectScriptAlg.setInParam(list);
		pas14ProjectService.editScriptAlg(projectScriptAlg);
		return projectScriptAlg;
	}
	/**
	 * 修改data-set
	 * @param projectId 模型信息
	 * @param taskDTO 任务信息
	 * @return
	 */
	public ProjectDataSet editDataSet(Long projectId,String nodeId,TaskDTO taskDTO) throws Exception {
		ProjectDataSet projectDataSet = pas14ProjectService.getDataSet(projectId,nodeId);
		//表名
		String groupId = taskDTO.getFieldGroupId();
		projectDataSet.setStmtTable("["+groupId+"]");
		// 时间条件
		List<PartitionInfo> partitionInfos = new ArrayList<>();
		PartitionInfo partitionInfo = new PartitionInfo();

		String from = DateFormatterUtil.parseToString(taskDTO.getStartDate(),DateFormatterUtil.dateTimeFormatter);
		String to = DateFormatterUtil.parseToString(taskDTO.getEndDate(),DateFormatterUtil.dateTimeFormatter);
		TimeObject timeObject = new TimeObject();
		timeObject.setFrom(from);
		timeObject.setTo(to);
		List<TimeObject> ts = new ArrayList<>();
		ts.add(timeObject);
		partitionInfo.setTs(ts);

		//过滤条件
		/*
		List<Device> devices = taskDTO.getDevice();
		Device device = devices.get(0);
		// channel_id
		CompoundId compoudId1 = new CompoundId();
		compoudId1.setFieldKey("channel_id");
		compoudId1.setCondition("=");
		String key = "";
//		String key = taskDTO.getPointData().getKey();
		compoudId1.setFieldValue(key.split("_")[1]);
		// factory_id
		String[] params = device.getDeviceNo().split("_");
		CompoundId factoryId = new CompoundId();
		factoryId.setFieldKey("factory_id");
		factoryId.setCondition("=");
		factoryId.setFieldValue(params[0]);
		// equipment_id
		CompoundId equipmentId = new CompoundId();
		equipmentId.setFieldKey("equipment_id");
		equipmentId.setCondition("=");
		equipmentId.setFieldValue(params[1]);
		//machine_id
		CompoundId machineId = new CompoundId();
		machineId.setFieldKey("machine_id");
		machineId.setCondition("=");
		machineId.setFieldValue(params[2]);
		List<CompoundId> compoudIds = new ArrayList<>();
//		compoudIds.add(compoudId);
		compoudIds.add(compoudId1);
		compoudIds.add(factoryId);
		compoudIds.add(equipmentId);
		compoudIds.add(machineId);
		partitionInfo.setCompoundId(compoudIds);*/


		partitionInfos.add(partitionInfo);
		projectDataSet.setPartitionInfo(partitionInfos);
		//stmtSelect 抽取字段
		List<StmtSelect> stmtSelects = new ArrayList<>();
		StmtSelect stmtSelect1 = new StmtSelect();
		stmtSelect1.setName("ts");
		stmtSelect1.setType("timestamp");
		StmtSelect stmtSelect2 = new StmtSelect();
		stmtSelect2.setName("factory_id");
		stmtSelect2.setType("string");
		StmtSelect stmtSelect3 = new StmtSelect();
		stmtSelect3.setName("equipment_id");
		stmtSelect3.setType("string");
		StmtSelect stmtSelect4 = new StmtSelect();
		stmtSelect4.setName("machine_id");
		stmtSelect4.setType("string");

		StmtSelect stmtSelect5 = new StmtSelect();
		stmtSelect5.setName("channel_type");
		stmtSelect5.setType("string");
		StmtSelect stmtSelect6 = new StmtSelect();
		stmtSelect6.setName("channel_id");
		stmtSelect6.setType("string");
		StmtSelect stmtSelect7 = new StmtSelect();
		stmtSelect7.setName("datatype");
		stmtSelect7.setType("string");
		stmtSelects.add(stmtSelect1);
		stmtSelects.add(stmtSelect2);
		stmtSelects.add(stmtSelect3);
		stmtSelects.add(stmtSelect4);
		stmtSelects.add(stmtSelect5);
		stmtSelects.add(stmtSelect6);
		stmtSelects.add(stmtSelect7);

		//where条件
		StringBuffer stmtWhere = new StringBuffer("");
		// factory_id
		if(taskDTO.getCustomer() != null){
			stmtWhere.append(" factory_id = '").append(taskDTO.getCustomer().getValue()).append("'");
		}
		// equipment_id
		List<Device> devices = taskDTO.getDevice();
		if(devices.size()>0){
			String equipmentId = devices.get(0).getDeviceNo().split("_")[1];
			stmtWhere.append(" and equipment_id = '"+equipmentId+"'");
		}

		if(taskDTO.getDeviceIds()!=null && taskDTO.getDeviceIds().size()>0){
			stmtWhere.append(" and (");
			for(int i =0; i<taskDTO.getDeviceIds().size();i++){
				if(i>0) {
					stmtWhere.append(" or ");
				}
				stmtWhere.append(" machine_id = '").append(taskDTO.getDeviceIds().get(i)).append("'");
			}
			stmtWhere.append(" ) ");
		}
		if(taskDTO.getChannelIds()!=null && taskDTO.getChannelIds().size()>0){
			stmtWhere.append(" and (");
			for(int i =0; i<taskDTO.getChannelIds().size();i++){
				if(i>0) {
					stmtWhere.append(" or ");
				}
				stmtWhere.append(" channel_id = '").append(taskDTO.getChannelIds().get(i)).append("'");
			}
			stmtWhere.append(" ) ");
		}
		projectDataSet.setStmtWhere(stmtWhere.toString());


		List<LabelValueKeyObject> varData = taskDTO.getVarData();
		for(LabelValueKeyObject stmtSelect:varData){
			String[] name_type = stmtSelect.getValue().split(",");
			StmtSelect stmtSelectOther = new StmtSelect();
			stmtSelectOther.setName(name_type[1]);
			stmtSelectOther.setType(name_type[0]);
			stmtSelects.add(stmtSelectOther);
		}
		projectDataSet.setStmtSelect(stmtSelects);
		pas14ProjectService.editDataSet(projectDataSet);
		return projectDataSet;
	}

	/**
	 * 编辑时间
	 * @param projectId
	 * @param start
	 * @param end
	 * @return
	 * @throws Exception
	 */
	public Long editDataSetTime(Long projectId,String start,String end) throws Exception {
		Project project = pas14ProjectService.getBasic(projectId);
		ProjectFlow flow = pas14ProjectService.getFlow(project.getId());
		ProjectNode[] nodes = flow.getNodes();
		for(ProjectNode node:nodes){
			if(node.getType().equals("data-set")){
				ProjectDataSet projectDataSet = pas14ProjectService.getDataSet(projectId,node.getId());
				List<PartitionInfo> partitionInfos = projectDataSet.getPartitionInfo();
				PartitionInfo partitionInfo = partitionInfos.get(0);
				TimeObject timeObject = new TimeObject();
				timeObject.setFrom(start);
				timeObject.setTo(end);
				List<TimeObject> ts = new ArrayList<>();
				ts.add(timeObject);
				partitionInfo.setTs(ts);
				projectDataSet.setPartitionInfo(partitionInfos);
				pas14ProjectService.editDataSet(projectDataSet);
			}
		}
		return projectId;
	}

	/**
	 * pas项目转换为本地模型对象
	 * @param project
	 * @return
	 * @throws Exception
	 */
	public Model projectToModel(Project project) throws Exception {
		Model model = new Model();
		model.setName(project.getProjName());
		model.setShortDesc(project.getDescription());
		model.setId(project.getId());
		//TODO 分析类型，后续不以分析类型分组，可优化
//		ProjectNode[] nodes = project.getFlow().getNodes();
		ProjectFlow flow = pas14ProjectService.getFlow(project.getId());
		ProjectNode[] nodes =flow.getNodes();
		for ( ProjectNode node : nodes) {
			if (node.getType().equals("script-alg")) {
				ProjectScriptAlg projectScriptAlg = pas14ProjectService.getScriptAlg(project.getId(),node.getId());
				// 分析类型
				model.setAnalysisType(projectScriptAlg.getAnalysisType());
				// 下载路径
				model.setDownloadUrl(pas14ProjectService.getURI(pas14ProjectService.getDownLoadUrl(project.getId(),projectScriptAlg.getMainScript())));
			} else {
				ProjectDataSet projectDataSet = pas14ProjectService.getDataSet(project.getId(),node.getId());
				String datasource = StringUtils.isEmpty(model.getDataSource())? projectDataSet.getDataSource() : model.getDataSource()+","+projectDataSet.getDataSource();
				model.setDataSource(datasource);
			}
		}
		Date createDate = new Date(project.getCreateTime());
		Date updateDate = new Date(project.getUpdateTime());
		model.setUpdateTime(DateFormatterUtil.UDateToLocalDateTime(updateDate));
		model.setCreateTime(DateFormatterUtil.UDateToLocalDateTime(createDate));
		model.setOwner(project.getOwner());
		model.setPicUrl(pas14ProjectService.getURI(pas14ProjectService.getServiceBasic()+project.getIconUrl()));
		return model;
	}

	/**
	 * 创建data-set
	 * @param project 模型信息
	 * @param taskDTO 任务信息
	 * @return
	 */
//	public ProjectDataSet createDataSet(Project project,TaskDTO taskDTO){
//		ProjectDataSet projectDataSet = new ProjectDataSet();
//		projectDataSet.setId(UUIDUtils.uuid());
//		projectDataSet.setProjId(project.getId());
//		projectDataSet.setName("kmx时序数据源");
//		projectDataSet.setDataSource("kmx");
//		projectDataSet.setDataType("csv");
//		projectDataSet.setParalType("byField");
//		String groupId = taskDTO.getPointData().getValue();
//		projectDataSet.setStmtTable("["+groupId+"]");//表名
//		projectDataSet.setOperationId(UUIDUtils.uuid());
//		// 时间条件
//		String from = DateFormatterUtil.parseToString(taskDTO.getStartDate(),DateFormatterUtil.dateTimeFormatter);
//		String to = DateFormatterUtil.parseToString(taskDTO.getEndDate(),DateFormatterUtil.dateTimeFormatter);
//		TimeObject timeObject = new TimeObject();
//		timeObject.setFrom(from);
//		timeObject.setTo(to);
//		PartitionInfo partitionInfo = new PartitionInfo();
//		List<TimeObject> ts = new ArrayList<>();
//		ts.add(timeObject);
//		partitionInfo.setTs(ts);
//		//过滤条件
//		List<Device> devices = taskDTO.getDevice();
//		List<String> deviceNos = new ArrayList<>();
//		devices.stream().forEach(device -> {
//			deviceNos.add(device.getDeviceNo());
//		});
//		CompoundId compoudId = new CompoundId();
//		compoudId.setFieldKey("deviceNo");
//		compoudId.setCondition("in");
//		compoudId.setFieldValue(deviceNos);
//		List<CompoundId> compoudIds = new ArrayList<>();
//		compoudIds.add(compoudId);
//		partitionInfo.setCompoundId(compoudIds);
//		//stmtSelect 抽取字段
//		List<StmtSelect> stmtSelects = new ArrayList<>();
//		StmtSelect stmtSelect1 = new StmtSelect();
//		stmtSelect1.setName("ts");
//		stmtSelect1.setType("timestamp");
//		StmtSelect stmtSelect2 = new StmtSelect();
//		stmtSelect2.setName("deviceNo");
//		stmtSelect2.setType("string");
//		stmtSelects.add(stmtSelect1);
//		stmtSelects.add(stmtSelect2);
//		List<LabelValueObject> varData = taskDTO.getVarData();
//		for(LabelValueObject stmtSelect:varData){
//			StmtSelect stmtSelect3 = new StmtSelect();
//			stmtSelect3.setName(stmtSelect.getLabel());
//			stmtSelect3.setType(stmtSelect.getValue());
//			stmtSelects.add(stmtSelect3);
//		}
//		projectDataSet.setStmtSelect(stmtSelects);
//		//extention
//		Map<String,Boolean> extention = new HashMap<>();
//		extention.put("pas.target.extraction.result.withTitle",true);
//		projectDataSet.setExtention(extention);
//		return projectDataSet;
//	}

}
